Skip to content

libstore: Fix pct-encoding issues in store references#15280

Merged
xokdvium merged 1 commit intomasterfrom
local-store-filesystem
Feb 26, 2026
Merged

libstore: Fix pct-encoding issues in store references#15280
xokdvium merged 1 commit intomasterfrom
local-store-filesystem

Conversation

@xokdvium
Copy link
Contributor

Motivation

When the common pattern for store config constructors is to accept
an arbitrary string it's unclear whether it needs pct-decoding or not.
Prior to c436b7a the string passed to
the constructors was a mix of encoded authority and decoded path concatenated
with a /. After that commit it accidentally started accepting pct-encoded
result of renderAuthorityAndPath, but only in some code paths. This lead to
file:///tmp/a+b to be created on disk in /tmp/a%2Bb directory. Similar issue
affected the less-known variant with local:///tmp/a+b. Regular store references
that are local paths were not affected.

This patch changes the constructors to accept different types to signify what
is actually needed to let the factory method handle this in a consistent way:

  • std::filesystem::path - local binary cache store and local store
  • ParsedURL::Authority - for ssh stores
  • ParsedURL - for http stores

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions bot added new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority store Issues and pull requests concerning the Nix store labels Feb 18, 2026
@xokdvium xokdvium force-pushed the local-store-filesystem branch from 9aae32b to 523d479 Compare February 18, 2026 10:37
@xokdvium
Copy link
Contributor Author

Has issues building on mingw for now

@xokdvium xokdvium marked this pull request as draft February 18, 2026 22:34
@Ericson2314 Ericson2314 force-pushed the local-store-filesystem branch 2 times, most recently from 19474c3 to 7e9ae05 Compare February 25, 2026 05:17
@github-actions github-actions bot added the repl The Read Eval Print Loop, "nix repl" command and debugger label Feb 25, 2026
@Ericson2314 Ericson2314 force-pushed the local-store-filesystem branch from 7e9ae05 to 481d605 Compare February 25, 2026 06:27
@Ericson2314
Copy link
Member

The MinGW build issues are fixed (thanks @amaanq) and the / safety issues that @xokdvium and I discussed are also fixed using CanonPath and CanonPath::fromSingleSegment technique that we separately discussed. (This is done in the middle two commits, which I just added.)


try {
getFile(info->url, *decompressor);
getFile(CanonPath{"/" + info->url}, *decompressor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC @xokdvium and I had seen an example in the Harmonia integration test of an absolute URL being used here? That would not break. We might want to double check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They weren't absolute. Stuff like nar-bridge from snix uses relative references with query parameters:

curl: [HTTP/2] [13] [:method: GET]
curl: [HTTP/2] [13] [:scheme: https]
curl: [HTTP/2] [13] [:authority: nixos.snix.store]
curl: [HTTP/2] [13] [:path: /nar/snix-castore/CiUSIDx38iUK-ZuIbulax1ctEWOhHRUp25ujusl-vopC2DF_GJYC?narsize=511440]
curl: [HTTP/2] [13] [user-agent: curl/8.18.0 Nix/2.34.0pre20260226_db06ac4]
curl: [HTTP/2] [13] [accept: */*]
curl: [HTTP/2] [13] [accept-encoding: deflate, gzip, br, zstd]


void HttpBinaryCacheStore::upsertFile(
const std::string & path, RestartableSource & source, const std::string & mimeType, uint64_t sizeHint)
const CanonPath & path, RestartableSource & source, const std::string & mimeType, uint64_t sizeHint)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure the API must not change. We can use CanonPath just in the local binary cache store implementation though

@Ericson2314 Ericson2314 force-pushed the local-store-filesystem branch 4 times, most recently from 54bd57f to 5adf9b0 Compare February 25, 2026 22:26
@github-actions github-actions bot added fetching Networking with the outside (non-Nix) world, input locking c api Nix as a C library with a stable interface labels Feb 25, 2026
@Ericson2314 Ericson2314 force-pushed the local-store-filesystem branch from 5adf9b0 to 667ad46 Compare February 25, 2026 23:51
@xokdvium
Copy link
Contributor Author

@Ericson2314, I'm a bit apprehensive about using CanonPath because the string might have query parameters too and that's certainly the wrong type for it. I have a less intrusive solution for now so that we can unblock the fixes.

@xokdvium xokdvium force-pushed the local-store-filesystem branch from 667ad46 to a4ebebe Compare February 26, 2026 13:34
@xokdvium xokdvium marked this pull request as ready for review February 26, 2026 13:37
When the common pattern for store config constructors is to accept
an arbitrary string it's unclear whether it needs pct-decoding or not.
Prior to c436b7a the string passed to
the constructors was a mix of encoded authority and decoded path concatenated
with a `/`. After that commit it accidentally started accepting pct-encoded
result of renderAuthorityAndPath, but only in some code paths. This lead to
file:///tmp/a+b to be created on disk in /tmp/a%2Bb directory. Similar issue
affected the less-known variant with local:///tmp/a+b. Regular store references
that are local paths were not affected.

This patch changes the constructors to accept different types to signify what
is actually needed to let the factory method handle this in a consistent way:

- std::filesystem::path - local binary cache store and local store
- ParsedURL::Authority - for ssh stores
- ParsedURL - for http stores

(Some MinGW build fixes by Amaan Qureshi <git@amaanq.com>)
@xokdvium xokdvium force-pushed the local-store-filesystem branch from a4ebebe to 224c818 Compare February 26, 2026 13:40
@Ericson2314
Copy link
Member

@xokdvium OK fair point with the query params in the path case.

@xokdvium xokdvium added this pull request to the merge queue Feb 26, 2026
Merged via the queue into master with commit 128688d Feb 26, 2026
51 of 55 checks passed
@xokdvium xokdvium deleted the local-store-filesystem branch February 26, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c api Nix as a C library with a stable interface fetching Networking with the outside (non-Nix) world, input locking new-cli Relating to the "nix" command repl The Read Eval Print Loop, "nix repl" command and debugger store Issues and pull requests concerning the Nix store with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants